/**
 * Copyright (c), 上海沃恩信息科技有限公司.
 * All rights reserved.
 * Licensed under BSD (https://www.pittypat.work/bsd.html).
 */

package com.waln.authority.authentication;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.waln.authority.authentication.data.App;
import com.waln.authority.authentication.data.Module;

import pittypat.DataList;
import pittypat.INavApp;
import pittypat.INavModule;
import pittypat.NavList;

/**
 * 定义一个 App 的导航项目。
 */
final class NavApp implements INavApp {
	private App app;
	private String iconUrl;
	private List<INavModule> modules;

	/**
	 * 使用应用信息、开发者代码和应用标识符初始化 NavApp 的新实例。
	 * 
	 * @param app
	 *            应用信息。
	 * @param developerCode
	 *            开发者代码小写形式，用于创建图标路径。
	 * @param appIdentifier
	 *            应用标识符小写形式，用于创建图标路径。
	 */
	public NavApp(App app, String developerCode, String appIdentifier) {
		this.app = app;
		this.iconUrl = String.format("~/com/%s/%s/app.png", developerCode, appIdentifier);
		this.modules = new ArrayList<>(app.moduleCount == null ? 0 : app.moduleCount);
	}

	/**
	 * 获取 App 的 Id。
	 * 
	 * @return App 的 Id。
	 */
	@Override
	public UUID getId() {
		return this.app.id;
	}

	/**
	 * 获取 App 的名称。
	 * 
	 * @return App 的名称。
	 */
	@Override
	public String getName() {
		return this.app.name;
	}

	/**
	 * 获取 App 的版本号。
	 * 
	 * @return App 的版本号。
	 */
	@Override
	public String getVersion() {
		return this.app.version;
	}

	/**
	 * 获取 App 的描述信息，通常用于作为工具提示。
	 * 
	 * @return App 的描述信息，通常用于作为工具提示。
	 */
	@Override
	public String getDescription() {
		return this.app.description;
	}

	/**
	 * 获取 App 的图标文件的路径。
	 * 
	 * @return App 的图标文件的路径。
	 */
	@Override
	public String getIconUrl() {
		return this.iconUrl;
	}

	/**
	 * 获取目标 App 中包含的所有模块。
	 * 
	 * @return 目标 App 中包含的所有模块。
	 */
	@Override
	public List<INavModule> getModules() {
		return this.modules;
	}

	/**
	 * 将当前对象作为 JSON 字符串写入指定的文本流。
	 * 
	 * @param writer
	 *            目标文本流。
	 * @throws IOException
	 */
	@Override
	public void write(Writer writer) throws IOException {
		if (writer == null) {
			throw new IllegalArgumentException("writer 为 null。");
		}

		writer.write('{');

		// Id
		writer.write("\"id\":");
		pittypat.Json.write(writer, this.app.id);
		writer.write(',');

		// 名称
		writer.write("\"name\":");
		pittypat.Json.write(writer, this.app.name);
		writer.write(',');

		// 版本
		writer.write("\"version\":");
		pittypat.Json.write(writer, this.app.version);
		writer.write(',');

		// 描述
		writer.write("\"description\":");
		pittypat.Json.write(writer, this.app.description);
		writer.write(',');

		// 描述
		writer.write("\"iconUrl\":");
		pittypat.Json.write(writer, this.iconUrl);
		writer.write(',');

		// 模块列表
		writer.write("\"modules\":[");

		int count = this.modules.size();
		if (count > 0) {
			for (int i = 0; i < count; ++i) {
				this.modules.get(i).write(writer);
				if (i < count - 1) {
					writer.write(',');
				}
			}
		}

		writer.write(']');

		writer.write('}');
	}

	/**
	 * 从数据集合中创建完整的导航列表。
	 * 
	 * @param apps
	 *            从数据服务中查询到的应用信息列表。
	 * @param modules2
	 *            从数据服务中查询到的模块信息列表。
	 * @return 一个要发送到客户端的导航列表。
	 */
	public static NavList toNavApps(DataList<App> apps, DataList<Module> modules) {
		if (apps == null || modules == null || apps.size() == 0 || modules.size() == 0) {
			return NavList.EMPTY;
		}

		List<INavApp> appList = new ArrayList<>(apps.size());
		NavApp app = null;
		String developerCode = null;
		String appIdentifier = null;

		for (App appItem : apps) {
			if (appItem != null) {
				developerCode = appItem.developerCode.toLowerCase();
				appIdentifier = appItem.identifier.toLowerCase();

				app = new NavApp(appItem, developerCode, appIdentifier);
				appList.add(app);

				for (Module moduleItem : modules) {
					if (moduleItem != null && moduleItem.appId.equals(app.getId())) {
						app.modules.add(new NavModule(moduleItem, developerCode, appIdentifier));
					}
				}
			}
		}

		return new NavList(appList);
	}
}
